package frame.options.simulation.results.virtual.graphical;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane;

import model.components.links.link.BWbackupFlag;
import model.components.links.link.Link;
import model.components.links.link.SdnLink;
import model.components.links.link.VirtualLink;
import model.components.networks.sdn.SdnNetwork;
import model.components.networks.virtual.VirtualNetwork;
import model.components.nodes.node.Node;
import model.components.nodes.node.sdn.SdnNode;
import model.components.nodes.node.sdn.SdnRouter;
import model.components.nodes.node.sdn.SdnServer;
import model.components.nodes.node.sdn.SdnSwitch;
import model.components.nodes.node.virtual.VirtualMachine;
import model.components.nodes.node.virtual.VirtualNode;
import model.components.nodes.node.virtual.VirtualRouter;
import model.components.nodes.node.virtual.VirtualSwitch;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.AbstractPopupGraphMousePlugin;
import frame.options.simulation.results.ResultsFrame;
import frame.options.simulation.results.sdn.graphical.SdnNetworkViewersPanel;

public class VirtualNetworkPlugin extends AbstractPopupGraphMousePlugin implements ActionListener
{
	public static final String ALL_VIRTUAL_LINK = "All Virtual Link";
	public static final String ALL_NO_BACKUP_VIRTUAL_LINK = "All No Backup Virtual Link";
	public static final String ALL_BACKUP_VIRTUAL_LINK = "All Backup Virtual Link";
	
	public static final String ALL_VIRTUAL_NETWORK = "All Virtual Network";
	public static final String ALL_NO_BACKUP_VIRTUAL_NETWORK = "All No Backup Virtual Network";
	public static final String ALL_BACKUP_VIRTUAL_NETWORK = "All Backup Virtual Network";
	
	private VirtualNode virtualNode;
	public VirtualNode getVirtualNode(){ return virtualNode; }
	public void setVirtualNode( VirtualNode virtualNode ){ this.virtualNode = virtualNode; }
	
	private JPopupMenu virtualNodePopupMenu;
	public JPopupMenu getVirtualNodePopupMenu(){ return virtualNodePopupMenu; }
	public void setVirtualNodePopupMenu( JPopupMenu virtualNodePopupMenu ){ this.virtualNodePopupMenu = virtualNodePopupMenu; }
	
	private VirtualLink virtualLink;
	public VirtualLink getVirtualLink(){ return virtualLink; }
	public void setVirtualLink( VirtualLink virtualLink ){ this.virtualLink = virtualLink; }
	
	private JPopupMenu virtualLinkPopupMenu;
    public JPopupMenu getVirtualLinkPopupMenu(){ return virtualLinkPopupMenu; }
	public void setVirtualLinkPopupMenu( JPopupMenu virtualLinkPopupMenu ){ this.virtualLinkPopupMenu = virtualLinkPopupMenu; }
	
	private ResultsFrame resultsFrame;
	public ResultsFrame getResultsFrame(){ return resultsFrame; }
	public void setResultsFrame( ResultsFrame resultsFrame ){ this.resultsFrame = resultsFrame; }
	
	public VirtualNetworkPlugin( ResultsFrame resultsFrame )
    {
    	super( InputEvent.BUTTON3_MASK );
    	
    	this.setResultsFrame( resultsFrame );
    	
    	this.setVirtualNodePopupMenu( new JPopupMenu() );
    	this.setVirtualLinkPopupMenu( new JPopupMenu() );
    }
	
	@Override@SuppressWarnings("unchecked")
    protected void handlePopup( MouseEvent mouseEvent )
    {
		VisualizationViewer< Node, Link > visualizationViewer = (VisualizationViewer< Node, Link >) mouseEvent.getSource();
	    	
		VirtualNode virtualNode = (VirtualNode) visualizationViewer.getPickSupport().getVertex( visualizationViewer.getGraphLayout(), mouseEvent.getPoint().getX(), mouseEvent.getPoint().getY() );
		this.setVirtualNode( virtualNode );
	    	
		VirtualLink virtualLink = (VirtualLink) visualizationViewer.getPickSupport().getEdge( visualizationViewer.getGraphLayout(), mouseEvent.getPoint().getX(), mouseEvent.getPoint().getY() );
		this.setVirtualLink( virtualLink );
	    	
		if( virtualNode != null )
		{
			this.updateVirtualNodePopupMenu( virtualNode );
			this.getVirtualNodePopupMenu().show( visualizationViewer, mouseEvent.getX(), mouseEvent.getY() );
		}
		else if( virtualLink != null )	
		{
			this.updateVirtualLinkPopupMenu( virtualLink );
			this.getVirtualLinkPopupMenu().show( visualizationViewer, mouseEvent.getX(), mouseEvent.getY() );
		}
    }
	
	private void updateVirtualNodePopupMenu( VirtualNode virtualNode )
    {
		this.getVirtualNodePopupMenu().removeAll();
		this.getVirtualNodePopupMenu().add( this.virtualNodeMenuItem( virtualNode ) );
		
		if( virtualNode.getSdnNode() != null )
		{
			this.getVirtualNodePopupMenu().addSeparator();
			this.getVirtualNodePopupMenu().add( this.sdnNodeMenuItem( virtualNode ) );
			
			this.getVirtualNodePopupMenu().addSeparator();
			this.getVirtualNodePopupMenu().add( this.allVirtualNetworkMenuItem( virtualNode ) );
		}
    }
	private JMenuItem virtualNodeMenuItem( VirtualNode virtualNode )
	{
		Icon icon = null;
		
		if( virtualNode.isSelected() )
			icon = virtualNode.getGreenIcon();
		else if( virtualNode.getSdnNode() != null )
			icon = virtualNode.getYellowIcon();
		else
			icon = virtualNode.getGreyIcon();
    	
		String text = null;
		
    	if( virtualNode instanceof VirtualRouter || virtualNode instanceof VirtualSwitch )
    		text = "<html><b>" + virtualNode.getNetworkName() + ": </b>" + virtualNode.getName() + "<br><b>OS: </b>" + virtualNode.getOS() + "<br><b>CPU: </b>" + virtualNode.getCPU() + " <b>RAM: </b>" + virtualNode.getRAM() + "</html>";
    	else if( virtualNode instanceof VirtualMachine )
    		text = "<html><b>" + virtualNode.getNetworkName() + ": </b>" + virtualNode.getName() + "<br><b>OS: </b>" + virtualNode.getOS() + "<br><b>CPU: </b>" + virtualNode.getCPU() + " <b>RAM: </b>" + virtualNode.getRAM() + " <b>STORAGE: </b>" + virtualNode.getStorage() + "</html>";
		
    	JMenuItem menuItem = new JMenuItem();
    	menuItem.setIcon( icon );
    	menuItem.setText( text );
    	menuItem.addActionListener( this );
    	
    	return menuItem;
	}
	private JMenuItem sdnNodeMenuItem( VirtualNode virtualNode )
	{
		Icon icon = null;
		
		SdnNode sdnNode = virtualNode.getSdnNode();
		
		if( virtualNode.isSelected() )
			icon = sdnNode.getGreenIcon();
		else
			icon = sdnNode.getYellowIcon();
		
		String text = null;
		
		if( sdnNode instanceof SdnRouter || sdnNode instanceof SdnSwitch )
			text = "<html><b>" + sdnNode.getNetworkName() + ": </b>" + sdnNode.getName() + "<br><b>OS: </b>" + sdnNode.getOS() + "<br><b>CPU: </b>" + sdnNode.getCPU() + "(" + ( sdnNode.getCPU() - sdnNode.getAvailableCPU() ) + ")" + " <b>RAM: </b>" + sdnNode.getRAM() + "(" + ( sdnNode.getRAM() - sdnNode.getAvailableRAM() ) + ")" + "</html>";
		else if( sdnNode instanceof SdnServer )
			text = "<html><b>" + sdnNode.getNetworkName() + ": </b>" + sdnNode.getName() + "<br><b>OS: </b>" + sdnNode.getOS() + "<br><b>CPU: </b>" + sdnNode.getCPU() + "(" + ( sdnNode.getCPU() - sdnNode.getAvailableCPU() ) + ")" + " <b>RAM: </b>" + sdnNode.getRAM() + "(" + ( sdnNode.getRAM() - sdnNode.getAvailableRAM() ) + ")" + " <b>STORAGE: </b>" + sdnNode.getStorage() + "(" + ( sdnNode.getStorage() - sdnNode.getAvailableStorage() ) + ")" + "</html>";
		
		JMenuItem menuItem = new JMenuItem();
		menuItem.setIcon( icon );
		menuItem.setText( text );
		menuItem.addActionListener( this );
        	
		return menuItem;
	}
	private JMenuItem allVirtualNetworkMenuItem( VirtualNode virtualNode )
	{
		JMenuItem menuItem = new JMenuItem();
		menuItem.setName( ALL_VIRTUAL_NETWORK );
		menuItem.setIcon( virtualNode.getGreyIcon() );
		menuItem.setText( "<html><b>" + ALL_VIRTUAL_NETWORK + "</b></html>" );
		menuItem.addActionListener( this );
		
		return menuItem;
	}
	
	private void updateVirtualLinkPopupMenu( VirtualLink virtualLink )
	{
		VirtualNode firstVirtualNode = (VirtualNode) virtualLink.getFirstNode();
		VirtualNode secondVirtualNode = (VirtualNode) virtualLink.getSecondNode();
		
		SdnNode firstSdnNode = firstVirtualNode.getSdnNode();
		SdnNode secondSdnNode = secondVirtualNode.getSdnNode();
		
		this.getVirtualLinkPopupMenu().removeAll();
		this.getVirtualLinkPopupMenu().add( this.virtualLinkMenuItem( virtualLink ) );
			
    	if( virtualLink.getSdnLinksBWbackupFlags().size() == 0 && firstSdnNode != null && secondSdnNode != null  )
    	{
	    	this.getVirtualLinkPopupMenu().addSeparator();
			this.getVirtualLinkPopupMenu().add( this.sdnLinkMenuItem( null, virtualLink ) );
    	}
    	else if( virtualLink.getSdnLinksBWbackupFlags().size() != 0 )
    	{
	    	LinkedHashMap< SdnLink, BWbackupFlag > sdnLinks = virtualLink.getSdnLinksBWbackupFlags();
	    	LinkedHashMap< SdnLink, BWbackupFlag > noBackupSdnLinks = new LinkedHashMap< SdnLink, BWbackupFlag >();
	    	LinkedHashMap< SdnLink, BWbackupFlag > backupSdnLinks = new LinkedHashMap< SdnLink, BWbackupFlag >();
	    	
			this.getVirtualLinkPopupMenu().addSeparator();
			this.getVirtualLinkPopupMenu().add( this.allVirtualNetworkMenuItem( virtualLink ) );
	    	
	    	if( sdnLinks.size() != 0 )
	    	{
		    	Iterator< Entry< SdnLink, BWbackupFlag > > iterator = virtualLink.getSdnLinksBWbackupFlags().entrySet().iterator();
				
		    	while( iterator.hasNext() )
				{
					Entry< SdnLink, BWbackupFlag > entry = iterator.next();
					
					if( entry.getValue().getBackupFlag() == 0 )
						noBackupSdnLinks.put( entry.getKey(), entry.getValue() );
					
					else if( entry.getValue().getBackupFlag() == 1 )
						backupSdnLinks.put( entry.getKey(), entry.getValue() );
				}
	    	}
	    	
	    	if( noBackupSdnLinks.size() != 0 )
	    	{
	    		this.getVirtualLinkPopupMenu().addSeparator();
	    		this.getVirtualLinkPopupMenu().add( this.normalVirtualLinkMenuItem( virtualLink ) );
	    		
	    		Iterator< Entry< SdnLink, BWbackupFlag > > iterator = noBackupSdnLinks.entrySet().iterator();
	    		
				while( iterator.hasNext() )
				{
					this.getVirtualLinkPopupMenu().addSeparator();
					this.getVirtualLinkPopupMenu().add( this.sdnLinkMenuItem( iterator.next(), virtualLink ) );
				}
				
				this.getVirtualLinkPopupMenu().addSeparator();
				this.getVirtualLinkPopupMenu().add( this.normalAllVirtualNetworkMenuItem( virtualLink ) );
	    	}
	    	
	    	if( backupSdnLinks.size() != 0 )
	    	{
	    		this.getVirtualLinkPopupMenu().addSeparator();
	    		this.getVirtualLinkPopupMenu().add( this.backupVirtualLinkMenuItem( virtualLink ) );
	    		
	    		Iterator< Entry< SdnLink, BWbackupFlag > > iterator = backupSdnLinks.entrySet().iterator();
	    		
				while( iterator.hasNext() )
				{
					this.getVirtualLinkPopupMenu().addSeparator();
					this.getVirtualLinkPopupMenu().add( this.sdnLinkMenuItem( iterator.next(), virtualLink ) );
				}
				
				this.getVirtualLinkPopupMenu().addSeparator();
				this.getVirtualLinkPopupMenu().add( this.backupAllVirtualNetworkMenuItem( virtualLink ) );
	    	}
    	}
	}
	private JMenuItem virtualLinkMenuItem( VirtualLink virtualLink )
	{
		VirtualNode firstNode = (VirtualNode) virtualLink.getFirstNode();
		VirtualNode secondNode = (VirtualNode) virtualLink.getSecondNode();
		
		JMenuItem menuItem = new JMenuItem();
		
		if( firstNode.getSdnNode() != null )
			menuItem.setText( "<html><b>" + virtualLink.getNetworkName() + ": </b>" + virtualLink.getName() + " <b>BW: </b> " + virtualLink.getBW() + "<br><b>Endpoint 1: </b>" + firstNode.getName() + " (<FONT COLOR=\"green\">" + firstNode.getSdnNode().getName() + "</FONT>)" + "<br><b>Endpoint 2: </b>" + secondNode.getName() + " (<FONT COLOR=\"green\">" + secondNode.getSdnNode().getName() + "</FONT>)" + "</html>" );
		else
			menuItem.setText( "<html><b>" + virtualLink.getNetworkName() + ": </b>" + virtualLink.getName() + " <b>BW: </b> " + virtualLink.getBW() + "<br><b>Endpoint 1: </b>" + firstNode.getName() + "<br><b>Endpoint 2: </b>" + secondNode.getName() + "</html>" );

		menuItem.setName( ALL_VIRTUAL_LINK );
    	menuItem.setIcon( virtualLink.getIcon() );
    	menuItem.addActionListener( this );
    	
    	return menuItem;
	}
	private JMenuItem allVirtualNetworkMenuItem( VirtualLink virtualLink )
	{
		JMenuItem menuItem = new JMenuItem();
		menuItem.setName( ALL_VIRTUAL_NETWORK );
		menuItem.setIcon( virtualLink.getIcon() );
		menuItem.setText( "<html><b>" + ALL_VIRTUAL_NETWORK + "</b></html>" );
		menuItem.addActionListener( this );
		
		return menuItem;
	}
	private JMenuItem normalVirtualLinkMenuItem( VirtualLink virtualLink )
	{
		Iterator< Entry< SdnLink, BWbackupFlag > > iterator = virtualLink.getSdnLinksBWbackupFlags().entrySet().iterator();
		int distanceTotal = 0;
		
		while( iterator.hasNext() )
		{
			Entry< SdnLink, BWbackupFlag > entry = iterator.next();
			
			if( entry.getValue().getBackupFlag() == 0 )
				distanceTotal += entry.getKey().getDistance();
		}
		
		JMenuItem menuItem = new JMenuItem();
    	menuItem.setText( "<html><b>" + virtualLink.getNetworkName() + ": </b>" + virtualLink.getName() + "<br><b>Endpoints: </b>" + virtualLink.getFirstNode().getName() + "-" + virtualLink.getSecondNode().getName() + "<br><b>Backup: </b> No" + " <b>BW: </b> " + virtualLink.getBW() + " <b>Distance: </b> " + distanceTotal + "</html>" );
    	menuItem.setName( ALL_NO_BACKUP_VIRTUAL_LINK );
    	menuItem.setIcon( virtualLink.getIcon() );
    	menuItem.addActionListener( this );
    	
    	return menuItem;
	}
	private JMenuItem normalAllVirtualNetworkMenuItem( VirtualLink virtualLink )
	{
		JMenuItem menuItemAllNetwork = new JMenuItem();
		menuItemAllNetwork.setName( ALL_NO_BACKUP_VIRTUAL_NETWORK );
		menuItemAllNetwork.setIcon( virtualLink.getIcon() );
		menuItemAllNetwork.setText( "<html><b>" + ALL_NO_BACKUP_VIRTUAL_NETWORK + "</b></html>" );
		menuItemAllNetwork.addActionListener( this );
		
		return menuItemAllNetwork;
	}
	private JMenuItem backupVirtualLinkMenuItem( VirtualLink virtualLink )
	{
		Iterator< Entry< SdnLink, BWbackupFlag > > iterator = virtualLink.getSdnLinksBWbackupFlags().entrySet().iterator();
		double distanceTotal = 0;
		
		while( iterator.hasNext() )
		{
			Entry< SdnLink, BWbackupFlag > entry = iterator.next();
			
			if( entry.getValue().getBackupFlag() == 1 )
				distanceTotal += entry.getKey().getDistance();
		}
		
		JMenuItem menuItem = new JMenuItem();
		menuItem.setText( "<html><b>" + virtualLink.getNetworkName() + ": </b>" + virtualLink.getName() + "<br><b>Endpoints: </b>" + virtualLink.getFirstNode().getName() + "-" + virtualLink.getSecondNode().getName() + "<br><b>Backup: </b> Yes" + " <b>BW: </b> " + virtualLink.getBW() + " <b>Distance: </b> " + distanceTotal + "</html>" );
    	menuItem.setName( ALL_BACKUP_VIRTUAL_LINK );
    	menuItem.setIcon( virtualLink.getIcon() );
    	menuItem.addActionListener( this );
    	
    	return menuItem;
	}
	private JMenuItem backupAllVirtualNetworkMenuItem( VirtualLink virtualLink )
	{
		JMenuItem menuItem = new JMenuItem();
		menuItem.setName( ALL_BACKUP_VIRTUAL_NETWORK );
		menuItem.setIcon( virtualLink.getIcon() );
		menuItem.setText( "<html><b>" + ALL_BACKUP_VIRTUAL_NETWORK + "</b></html>" );
		menuItem.addActionListener( this );
		
		return menuItem;
	}
	private JMenuItem sdnLinkMenuItem( Entry< SdnLink, BWbackupFlag > entry, VirtualLink virtualLink )
	{	
		VirtualNode firstVirtualEndpoint = (VirtualNode) virtualLink.getFirstNode();
    	VirtualNode secondVirtualEndpoint = (VirtualNode) virtualLink.getSecondNode();
		
    	SdnNode firstSdnEndpoint = firstVirtualEndpoint.getSdnNode();
    	SdnNode secondSdnEndpoint = secondVirtualEndpoint.getSdnNode();
		
    	Icon icon = null;
		String name = null;
		String text = null;
		JMenuItem menuItem = new JMenuItem();
		
    	if( entry != null )
    	{
    		SdnLink sdnLink = entry.getKey();
			SdnNode firstSdnNode = (SdnNode) sdnLink.getFirstNode();
			SdnNode secondSdnNode = (SdnNode) sdnLink.getSecondNode();
			icon = sdnLink.getIcon();
			name = sdnLink.getName() + "-" + sdnLink.getNetworkName();
			
			text = "<html><b>" + sdnLink.getNetworkName() + ": </b>" + sdnLink.getName() + " <b>BW: </b>" + sdnLink.getBW() + "(" + ( sdnLink.getBW() - sdnLink.getAvailableBW() ) + ")";
			
			text += "<br><b>Endpoints: </b>";
			
			if( firstSdnNode.getNumber() == firstSdnEndpoint.getNumber() || firstSdnNode.getNumber() == secondSdnEndpoint.getNumber() )
				text += "<FONT COLOR=\"green\">" + firstSdnNode.getName() + "</FONT>";
			else
				text += firstSdnNode.getName();

			text += "-";
			
			if( secondSdnNode.getNumber() == firstSdnEndpoint.getNumber() || secondSdnNode.getNumber() == secondSdnEndpoint.getNumber() )
				text += "<FONT COLOR=\"green\">" + secondSdnNode.getName() + "</FONT>";
			else
				text += secondSdnNode.getName();
			
			if( entry.getValue().getBackupFlag() == 0 )
				text += "<br><b>Backup: </b>No" + " <b>BW: </b>" + entry.getValue().getBW() + " <b>Distance:</b> " + sdnLink.getDistance() + "</html>";
			else if( entry.getValue().getBackupFlag() == 1 )
				text += "<br><b>Backup: </b>Yes" + " <b>BW: </b>" + entry.getValue().getBW() + " <b>Distance:</b> " + sdnLink.getDistance() + "</html>";
    		
			menuItem.addActionListener( this );
    	}
		else
		{
			icon = new ImageIcon( this.getClass().getResource(  "/icons/physicalLink.png" ) );
			text = "<html><b>Link between</b> " + firstSdnEndpoint.getNetworkName() + " <b>and</b> " + secondSdnEndpoint.getNetworkName() + "</html>";
		}
    	
		menuItem.setIcon( icon );
		menuItem.setName( name );
    	menuItem.setText( text );
    	
		return menuItem;
	}
	
	@Override
	public void actionPerformed( ActionEvent actionEvent )
	{	
		this.deSelectSdnNetworks();
		this.deSelectVirtualNetworks();
		
		VirtualNode pickedVirtualNode = this.getVirtualNode();
		VirtualLink pickedVirtualLink = this.getVirtualLink();
		
		String nameMenuItem = ( (JMenuItem) actionEvent.getSource() ).getName();
						
		if( nameMenuItem != null && nameMenuItem.equals( ALL_VIRTUAL_NETWORK ) )
		{
			String virtualNetworkName = null;
			String sdnNetworkName = null;
			int timeStamp = -1;
			
			if( pickedVirtualNode != null && pickedVirtualNode.getSdnNode() != null )
			{
				virtualNetworkName = pickedVirtualNode.getNetworkName();
				sdnNetworkName = pickedVirtualNode.getSdnNode().getNetworkName();
				timeStamp = pickedVirtualNode.getTimeStamp();
			}
			else if( pickedVirtualLink != null && pickedVirtualLink.getSdnLinksBWbackupFlags().size() > 0 )
			{
				virtualNetworkName = pickedVirtualLink.getNetworkName();
				sdnNetworkName = pickedVirtualLink.getSdnLinksBWbackupFlags().entrySet().iterator().next().getKey().getNetworkName();
				timeStamp = pickedVirtualLink.getTimeStamp();
			}
			
			VirtualNetwork virtualNetwork = this.virtualNetworkByTimeStamp( virtualNetworkName, timeStamp );
				
			for( VirtualNode virtualNode: virtualNetwork.getVirtualNodes() )
				if( virtualNode.getSdnNode().getNetworkName().equals( sdnNetworkName ) )
					virtualNode.setSelected( true );
					
			for( VirtualLink virtualLink: virtualNetwork.getVirtualLinks() )
				if( virtualLink.getSdnLinksBWbackupFlags().size() > 0 && sdnNetworkName.equals( virtualLink.getSdnLinksBWbackupFlags().entrySet().iterator().next().getKey().getNetworkName() ) )
				{
					virtualLink.setSelected( true );
					virtualLink.getFirstNode().setSelected( true );
					virtualLink.getSecondNode().setSelected( true );
				}
			
			SdnNetwork sdnNetwork = this.sdnNetworkByTimeStamp( sdnNetworkName, timeStamp );
			
			if( pickedVirtualNode != null )
				for( SdnNode sdnNode: sdnNetwork.getSdnNodes() )
					if( sdnNode.getNumber() == pickedVirtualNode.getSdnNode().getNumber() )
					{
						sdnNode.setSelected( true );
						
						for( VirtualNode virtualNode: sdnNode.getVirtualNodes() )
							if( pickedVirtualNode.getNumber() == virtualNode.getNumber() )
							{
								virtualNode.setSelected( true );
								break;
							}
						
						break;
					}
			
			for( SdnLink sdnLink: sdnNetwork.getSdnLinks() )
			{
				Iterator< Entry< VirtualLink, BWbackupFlag > > iterator = sdnLink.getVirtualLinksBWbackupFlags().entrySet().iterator();
				
				while( iterator.hasNext() )
				{
					VirtualLink virtualLink = iterator.next().getKey();
					
					if( virtualNetworkName.equals( virtualLink.getNetworkName() ) )
					{
						sdnLink.setSelected( true );
						sdnLink.getFirstNode().setSelected( true );
						sdnLink.getSecondNode().setSelected( true );
						
						virtualLink.setSelected( true );
						break;
					}
				}
			}
		}
		else if( this.getVirtualNode() != null )
		{
			pickedVirtualNode.setSelected( true );
			
			if( pickedVirtualNode.getSdnNode() != null )
			{
				SdnNode pickedSdnNode = pickedVirtualNode.getSdnNode();
				String sdnNetworkName = pickedSdnNode.getNetworkName();
				int timeStamp = pickedVirtualNode.getTimeStamp();
				
				SdnNetwork sdnNetwork = this.sdnNetworkByTimeStamp( sdnNetworkName, timeStamp );
					
				for( SdnNode sdnNode: sdnNetwork.getSdnNodes() )
					if( sdnNode.getNumber() == pickedSdnNode.getNumber() )
					{
						sdnNode.setSelected( true );
						
						for( VirtualNode virtualNode: sdnNode.getVirtualNodes() )
							if( pickedVirtualNode.getNumber() == virtualNode.getNumber() )
							{
								virtualNode.setSelected( true );
								break;
							}
							
						break;
					}
			}
		}
		else if( this.getVirtualLink() != null )
		{
			pickedVirtualLink.setSelected( true );
			pickedVirtualLink.getFirstNode().setSelected( true );
			pickedVirtualLink.getSecondNode().setSelected( true );
			
			if( pickedVirtualLink.getSdnLinksBWbackupFlags().size() > 0 )
			{
				String sdnNetworkName = pickedVirtualLink.getSdnLinksBWbackupFlags().entrySet().iterator().next().getKey().getNetworkName();
				int timeStamp = pickedVirtualLink.getTimeStamp();
				SdnNetwork sdnNetwork = this.sdnNetworkByTimeStamp( sdnNetworkName, timeStamp );
				
				if( nameMenuItem.equals( ALL_VIRTUAL_LINK ) )
				{
					Iterator< Entry< SdnLink, BWbackupFlag > > iterator = pickedVirtualLink.getSdnLinksBWbackupFlags().entrySet().iterator();
					
					while( iterator.hasNext() )
					{
						SdnLink pickedSdnLink = iterator.next().getKey();
					
						for( SdnLink sdnLink: sdnNetwork.getSdnLinks() )
							if( sdnLink.getNumber() == pickedSdnLink.getNumber() )
							{
								sdnLink.setSelected( true );
								sdnLink.getFirstNode().setSelected( true );
								sdnLink.getSecondNode().setSelected( true );
								break;
							}
					}
				}
				else if( nameMenuItem.equals( ALL_NO_BACKUP_VIRTUAL_LINK ) )
				{
					Iterator< Entry< SdnLink, BWbackupFlag > > iterator = pickedVirtualLink.getSdnLinksBWbackupFlags().entrySet().iterator();
					
					while( iterator.hasNext() )
					{
						Entry< SdnLink, BWbackupFlag > entry = iterator.next();
						SdnLink pickedSdnLink = entry.getKey();
						int backupFlag = entry.getValue().getBackupFlag(); 
						
						if( backupFlag  == 0 )
							for( SdnLink sdnLink: sdnNetwork.getSdnLinks() )
								if( sdnLink.getNumber() == pickedSdnLink.getNumber() )
								{
									sdnLink.setSelected( true );
									sdnLink.getFirstNode().setSelected( true );
									sdnLink.getSecondNode().setSelected( true );
									break;
								}
					}
				}
				else if( nameMenuItem != null && nameMenuItem.equals( ALL_NO_BACKUP_VIRTUAL_NETWORK ) )
				{
					String virtualNetworkName = pickedVirtualLink.getNetworkName();
					VirtualNetwork virtualNetwork = this.virtualNetworkByTimeStamp( virtualNetworkName, timeStamp );
						
					for( VirtualNode virtualNode: virtualNetwork.getVirtualNodes() )
						if( virtualNode.getSdnNode().getNetworkName().equals( sdnNetworkName ) )
							virtualNode.setSelected( true );
							
					for( VirtualLink virtualLink: virtualNetwork.getVirtualLinks() )
						if( virtualLink.getSdnLinksBWbackupFlags().size() > 0 && sdnNetworkName.equals( virtualLink.getSdnLinksBWbackupFlags().entrySet().iterator().next().getKey().getNetworkName() ) )
						{
							virtualLink.setSelected( true );
							virtualLink.getFirstNode().setSelected( true );
							virtualLink.getSecondNode().setSelected( true );
						}
					
					for( SdnLink sdnLink: sdnNetwork.getSdnLinks() )
					{
						Iterator< Entry< VirtualLink, BWbackupFlag > > iterator = sdnLink.getVirtualLinksBWbackupFlags().entrySet().iterator();
						
						while( iterator.hasNext() )
						{
							Entry< VirtualLink, BWbackupFlag > entry = iterator.next();
							VirtualLink virtualLink = entry.getKey();
							int backupFlag = entry.getValue().getBackupFlag();
							
							if( backupFlag == 0 && virtualNetworkName.equals( virtualLink.getNetworkName() ) )
							{
								sdnLink.setSelected( true );
								sdnLink.getFirstNode().setSelected( true );
								sdnLink.getSecondNode().setSelected( true );
								
								virtualLink.setSelected( true );
								break;
							}
						}
					}
				}
				else if( nameMenuItem.equals( ALL_BACKUP_VIRTUAL_LINK ) )
				{
					Iterator< Entry< SdnLink, BWbackupFlag > > iterator = pickedVirtualLink.getSdnLinksBWbackupFlags().entrySet().iterator();
					
					while( iterator.hasNext() )
					{
						Entry< SdnLink, BWbackupFlag > entry = iterator.next();
						SdnLink pickedSdnLink = entry.getKey();
						int backupFlag = entry.getValue().getBackupFlag(); 
						
						if( backupFlag  == 1 )
							for( SdnLink sdnLink: sdnNetwork.getSdnLinks() )
								if( sdnLink.getNumber() == pickedSdnLink.getNumber() )
								{
									sdnLink.setSelected( true );
									sdnLink.getFirstNode().setSelected( true );
									sdnLink.getSecondNode().setSelected( true );
									break;
								}
					}
				}
				else if( nameMenuItem != null && nameMenuItem.equals( ALL_BACKUP_VIRTUAL_NETWORK ) )
				{
					String virtualNetworkName = pickedVirtualLink.getNetworkName();
					VirtualNetwork virtualNetwork = this.virtualNetworkByTimeStamp( virtualNetworkName, timeStamp );
						
					for( VirtualNode virtualNode: virtualNetwork.getVirtualNodes() )
						if( virtualNode.getSdnNode().getNetworkName().equals( sdnNetworkName ) )
							virtualNode.setSelected( true );
							
					for( VirtualLink virtualLink: virtualNetwork.getVirtualLinks() )
						if( virtualLink.getSdnLinksBWbackupFlags().size() > 0 && sdnNetworkName.equals( virtualLink.getSdnLinksBWbackupFlags().entrySet().iterator().next().getKey().getNetworkName() ) )
						{
							virtualLink.setSelected( true );
							virtualLink.getFirstNode().setSelected( true );
							virtualLink.getSecondNode().setSelected( true );
						}
					
					for( SdnLink sdnLink: sdnNetwork.getSdnLinks() )
					{
						Iterator< Entry< VirtualLink, BWbackupFlag > > iterator = sdnLink.getVirtualLinksBWbackupFlags().entrySet().iterator();
						
						while( iterator.hasNext() )
						{
							Entry< VirtualLink, BWbackupFlag > entry = iterator.next();
							VirtualLink virtualLink = entry.getKey();
							int type = entry.getValue().getBackupFlag();
							
							if( type == 1 && virtualNetworkName.equals( virtualLink.getNetworkName() ) )
							{
								sdnLink.setSelected( true );
								sdnLink.getFirstNode().setSelected( true );
								sdnLink.getSecondNode().setSelected( true );
								
								virtualLink.setSelected( true );
								break;
							}
						}
					}
				}
				else
				{
					for( SdnLink sdnLink: sdnNetwork.getSdnLinks() )
						if( sdnLink.getName().equals( nameMenuItem.split( "-" )[ 0 ] ) && sdnLink.getNetworkName().equals( nameMenuItem.split( "-" )[ 1 ] ) )
						{
							sdnLink.setSelected( true );
							sdnLink.getFirstNode().setSelected( true );
							sdnLink.getSecondNode().setSelected( true );
							break;
						}
				}
			}
		}
		
		this.getResultsFrame().getVirtualNetworksViewersPanelsTabbedPane().repaint();
		this.getResultsFrame().getSdnNetworksViewersPanelsTabbedPane().repaint();
	}
	private void deSelectSdnNetworks()
	{
		List< SdnNetworkViewersPanel > panels = this.getResultsFrame().getSdnNetworksViewersPanels();
		
		for( int i = 0; i < panels.size(); i++ )
		{
			List< SdnNetwork > sdnNetworks = panels.get( i ).getSdnNetworks();
			
			for( int j = 0; j < sdnNetworks.size(); j++ )
			{
				SdnNetwork sdnNetwork = sdnNetworks.get( j );
				
				for( SdnNode sdnNode: sdnNetwork.getSdnNodes() )
				{
					sdnNode.setSelected( false );
					
					for( VirtualNode virtualNode: sdnNode.getVirtualNodes() )
						virtualNode.setSelected( false );
				}
				
				for( SdnLink sdnLink: sdnNetwork.getSdnLinks() )
					sdnLink.setSelected( false );
			}
		}
	}
	private void deSelectVirtualNetworks()
	{
		List< VirtualNetworkViewersPanel > panels = this.getResultsFrame().getVirtualNetworksViewersPanels();
		
		for( int i = 0; i < panels.size(); i++ )
		{
			List< VirtualNetwork > virtualNetworks = panels.get( i ).getVirtualNetworks();
			
			for( int j = 0; j < virtualNetworks.size(); j++ )
			{
				VirtualNetwork virtualNetwork = virtualNetworks.get( j );
				
				for( VirtualNode virtualNode: virtualNetwork.getVirtualNodes() )
					virtualNode.setSelected( false );
				
				for( VirtualLink virtualLink: virtualNetwork.getVirtualLinks() )
					virtualLink.setSelected( false );
			}
		}
	}
	private SdnNetwork sdnNetworkByTimeStamp( String sdnNetworkName, int timeStamp )
	{
		JTabbedPane tabbedPane = this.getResultsFrame().getSdnNetworksViewersPanelsTabbedPane();
		int index = tabbedPane.indexOfTab( sdnNetworkName );
		SdnNetworkViewersPanel panel = this.getResultsFrame().getSdnNetworksViewersPanels().get( index );
		List< SdnNetwork > sdnNetworks = panel.getSdnNetworks();
		
		for( int i = 0; i < sdnNetworks.size(); i++ )
		{
			SdnNetwork sdnNetwork = sdnNetworks.get( i );
			
			if( sdnNetwork.getTimeStamp() == timeStamp )
			{
				tabbedPane.setSelectedIndex( index );
				panel.putValueSliderss( i );
				
				return sdnNetwork;
			}
		}
		
		return null;
	}
	private VirtualNetwork virtualNetworkByTimeStamp( String virtualNetworkName, int timeStamp )
	{
		JTabbedPane tabbedPane = this.getResultsFrame().getVirtualNetworksViewersPanelsTabbedPane();
		int index = tabbedPane.indexOfTab( virtualNetworkName );
		tabbedPane.setSelectedIndex( index );
		
		VirtualNetworkViewersPanel panel = this.getResultsFrame().getVirtualNetworksViewersPanels().get( index );
		List< VirtualNetwork > virtualNetworks = panel.getVirtualNetworks();
			
		for( int i = 0; i < virtualNetworks.size(); i++ )
			if( virtualNetworks.get( i ).getTimeStamp() == timeStamp )
				return virtualNetworks.get( i );
		
		return null;
	}

}
